package com.example.netty.Netty启动流程;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.AttributeKey;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;

/**
 * @author liupk
 * @date 2018/10/23
 */
public class NettyServer {
    
    public static void main(String[] args) {
    
        ServerBootstrap serverBootstrap = new ServerBootstrap();
    
        NioEventLoopGroup workers = new NioEventLoopGroup();
    
        NioEventLoopGroup boss = new NioEventLoopGroup();
        
        serverBootstrap
                .group(boss,workers)
                .channel(NioServerSocketChannel.class)
                /**给channel自定一些属性，其实就是给channel传递一个map*/
                .attr(AttributeKey.newInstance("serverName"),"shier")
                /**给每个连接请求自定一些属性,可以用来判断登录*/
                .childAttr(AttributeKey.newInstance("hasLogin"),true)
                /**给连接设置一些底层参数*/
                .childOption(ChannelOption.SO_KEEPALIVE,true) //开启心跳
                .childOption(ChannelOption.TCP_NODELAY,true)//减少网络交互次数
                /**给通道设置参数*/
                .option(ChannelOption.SO_BACKLOG,1024)//服务器创建连接慢可以适当调大参数
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
                        System.out.println("初始化连接成功");
                    }
                });
        bind(serverBootstrap,25);
    }
    
    private static void bind(ServerBootstrap serverBootstrap,int port){
        serverBootstrap.bind(port).addListener(new GenericFutureListener<Future<? super Void>>() {
            @Override
            public void operationComplete(Future<? super Void> future) throws Exception {
                if (future.isSuccess()){
                    System.out.println("端口绑定成功！端口号为："+port);
                }else {
                    System.out.println("端口绑定失败");
                    bind(serverBootstrap,port+1);
                }
            }
        });
    }
}